package com.yjq.programmer.interceptor.home;

import com.alibaba.fastjson.JSON;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.yjq.programmer.bean.CodeMsg;
import com.yjq.programmer.constant.RuntimeConstant;
import com.yjq.programmer.service.home.ICartService;
import com.yjq.programmer.util.JWTUtil;
import com.yjq.programmer.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


/**
 * 前台用户登录拦截器
 * @author Administrator
 *
 */
@Component
public class UserLoginInterceptor implements HandlerInterceptor{

	private Logger log = LoggerFactory.getLogger(UserLoginInterceptor.class);

	@Autowired
	private ICartService cartService;

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
		String requestURI = request.getRequestURI();  // 获取当前请求的路径
		String token = getTokenFromCookies(request.getCookies());

		// 如果不在需要验证的路径内，直接跳过验证
		if (isUrlExemptFromLogin(requestURI)) {
			return true;
		}

		try {
			DecodedJWT decodedJWT = JWTUtil.verifyToken(token);
			setUserAttributes(request, decodedJWT);
			request.setAttribute("cartTotal", cartService.total(Long.valueOf(decodedJWT.getClaim("id").asString())).getData());
		} catch (JWTVerificationException e) {
			handleTokenVerificationFailure(request, response, requestURI);
			return false;
		}

		return true;
	}

	private String getTokenFromCookies(Cookie[] cookies) {
		if (cookies != null) {
			for (Cookie cookie : cookies) {
				if ("my_token".equals(cookie.getName())) {
					return cookie.getValue();
				}
			}
		}
		return "";
	}

	private boolean isUrlExemptFromLogin(String requestURI) {
		for (String exemptUrl : RuntimeConstant.userNotNeedConfirmUrl) {
			if (requestURI.equals(exemptUrl)) {
				return true;
			}
		}
		return false;
	}

	private void setUserAttributes(HttpServletRequest request, DecodedJWT decodedJWT) {
		request.setAttribute("id", decodedJWT.getClaim("id").asString());
		request.setAttribute("username", decodedJWT.getClaim("username").asString());
		request.setAttribute("email", decodedJWT.getClaim("email").asString());
		request.setAttribute("phone", decodedJWT.getClaim("phone").asString());
		request.setAttribute("headPic", decodedJWT.getClaim("headPic").asString());
	}

	private void handleTokenVerificationFailure(HttpServletRequest request, HttpServletResponse response, String requestURI) {
		if (StringUtil.isAjax(request)) {
			sendAjaxErrorResponse(response);
		} else {
			redirectToLoginPage(response, requestURI);
		}
	}

	private void sendAjaxErrorResponse(HttpServletResponse response) {
		try {
			response.setCharacterEncoding("UTF-8");
			response.getWriter().write(JSON.toJSONString(CodeMsg.USER_SESSION_EXPIRED));
		} catch (IOException e) {
			log.error("AJAX error response failed: {}", e.getMessage());
		}
	}

	private void redirectToLoginPage(HttpServletResponse response, String requestURI) {
		try {
			log.info("Token invalid or expired, redirecting to login page. Current URL={}", requestURI);
			response.sendRedirect("/home/user/login");
		} catch (IOException e) {
			log.error("Redirect to login page failed: {}", e.getMessage());
		}
	}
}
